package com.skivingcloud.admin.sys.controller;


import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.skivingcloud.admin.annotation.ModifyAnnotaionFactory;
import com.skivingcloud.admin.annotation.UserOperateLog;
import com.skivingcloud.admin.sys.entity.SysUserMenu;
import com.skivingcloud.admin.sys.entity.SysUserStation;
import com.skivingcloud.admin.sys.entity.User;
import com.skivingcloud.admin.sys.entity.UserRes;
import com.skivingcloud.admin.sys.service.ISysUserRoleService;
import com.skivingcloud.admin.sys.service.ITenantService;
import com.skivingcloud.admin.sys.service.IUserService;
import com.skivingcloud.admin.utils.JacksonJsonUtil;
import com.skivingcloud.admin.utils.PasswordHelper;
import com.skivingcloud.admin.utils.UserUtil;
import com.skivingcloud.common.contants.Constant;
import com.skivingcloud.common.exception.BusinessException;
import com.skivingcloud.common.utils.PageUtils;
import com.skivingcloud.common.utils.R;
import com.skivingcloud.common.utils.TreeUtils;
import com.skivingcloud.common.utils.UuidUtil;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;


/**
 * <p>
 * 系统用户 前端控制器
 * </p>
 *
 * @author skivingcloud
 * @since 2022-01-28
 */
@RestController
@Api(tags = "用户管理相关接口")
@RequestMapping("/sys/user")
public class UserController {

	private static Logger log = LoggerFactory.getLogger(UserController.class);

	/**
	 * 正则表达式-强密码-【必填字母数字及特殊字符，且以字母开头，8位以上】
	 */
	public static final String REGEX_PASSWORD_STRONG = "^(?![0-9]+$)(?![^0-9]+$)(?![a-zA-Z]+$)(?![^a-zA-Z]+$)(?![a-zA-Z0-9]+$)[a-zA-Z0-9\\S]{8,}$";

	@Resource
	private IUserService userService;

	@Resource
	private ISysUserRoleService sysUserRoleService;
	@Resource
	private ITenantService tenantService;
	
	@PostMapping("/list")
	// @RequiresPermissions("sys:role:list")
	public R list(@RequestBody Map<String, Object> params) {
		// 如果不是超级管理员，则只查询自己租户的用户列表
		User user = UserUtil.getUser();
		PageUtils page = userService.queryPage(params, user);

		return R.ok().put("page", page);
	}

	/**
	 * 新增用户
	 * 
	 * @param param
	 * @return
	 */
	@UserOperateLog(module = "系统功能", methods = "save", description = "新增用户")
	@PostMapping("/save")
	@RequiresPermissions("sys:user:add")
	public R save(@RequestBody Map<String, Object> param) {
		try {
			User userOp = (User) UserUtil.getUser();
			String jsonStr = JSONObject.fromObject(param.get("user")).toString();
			User user = (User) JacksonJsonUtil.jsonToObj(new User(), jsonStr);
			String tenantId = "";
			if (userOp.getTenantId().equals(Constant.SUPER_ADMIN_TENANTID)) {
				tenantId = user.getTenantId();
			} else {
				tenantId = userOp.getTenantId();
			}
			boolean ckUserName = userService.checkUserName(user.getUsername(), tenantId);
			if (ckUserName) {
				return R.error("用户名已被占用");
			}
			user.setTenantId(tenantId);
			user.setCreateUserId(userOp.getId());
			LocalDateTime dateNow = LocalDateTime.now();
			user.setId(UuidUtil.get32UUID());
			user.setPassword(Constant.password);
			user.setCreateTime(dateNow);
			user = PasswordHelper.encryptPassword(user);
			userService.save(user);
			return R.ok();
		} catch (JsonParseException e) {
			log.error("无法解析参数", e);
			return R.error("无法解析参数");
		} catch (JsonMappingException e) {
			log.error("无法解析参数", e);
			return R.error("无法解析参数");
		} catch (IOException e) {
			log.error("无法解析参数", e);
			return R.error("无法解析参数");
		} catch (BusinessException e) {
			log.error(e.getMessage(), e);
			return R.error(e.getMessage());
		} catch (Exception e) {
			log.error("新增用户失败", e);
			return R.error("新增用户失败");
		}
	}

	/**
	 * 获取用户信息
	 * 
	 * @param userId
	 * @return
	 */
	@GetMapping("/info/{userId}")
	// @RequiresPermissions("sys:user:info") shiro权限校验
	public R info(@PathVariable("userId") String userId) {
		User user = userService.getById(userId);
		return R.ok().put("user", user);
	}

	/**
	 * 修改用户信息
	 * 
	 * @param param
	 * @return
	 */
	@UserOperateLog(module = "系统功能", methods = "update", description = "修改用户")
	@PostMapping("/update")
	@RequiresPermissions("sys:user:edit")
	public R update(@RequestBody Map<String, Object> param) {
		try {
			User userOp = (User) UserUtil.getUser();
			String jsonStr = JSONObject.fromObject(param.get("user")).toString();
			User user = (User) JacksonJsonUtil.jsonToObj(new User(), jsonStr);
			user.setLastChangeder(userOp.getId());
			user.setLastChnagedTime(LocalDateTime.now());
			userService.update(user);
			return R.ok();
		} catch (JsonParseException e) {
			log.error("无法解析参数", e);
			return R.error("无法解析参数");
		} catch (JsonMappingException e) {
			log.error("无法解析参数", e);
			return R.error("无法解析参数");
		} catch (IOException e) {
			log.error("无法解析参数", e);
			return R.error("无法解析参数");
		} catch (BusinessException e) {
			log.error(e.getMessage(), e);
			return R.error(e.getMessage());
		} catch (Exception e) {
			log.error("新增用户失败", e);
			return R.error("新增用户失败");
		}
	}

	/**
	 * 获取用户岗位信息
	 * 
	 * @param userId
	 * @return
	 */
	@GetMapping("/getUserStationList/{userId}")
	// @RequiresPermissions("sys:user:info") shiro权限校验
	public R getUserStationList(@PathVariable("userId") String userId) {
		List<SysUserStation> userStations = userService.getUserStationList(userId);
		return R.ok().put("stationList", userStations);
	}

	/**
	 * Title: 设置用户岗位
	 * Description: 仅设置用户岗位
	 *
	 * @param params {userId：用户id，stationIdList：岗位id数组}
	 * @return
	 */
	@UserOperateLog(module = "系统功能", methods = "setUserStation", description = "设置用户岗位", functionNo = "101041")
	@PostMapping("/setUserStation")
	public R setUserStation(@RequestBody Map<String, Object> params) {
		try {
			String userId = params.get("userId") == null ? null : params.get("userId").toString();
			if (userId == null) {
				return R.error(1, "请传入用户ID");
			}
			JSONArray jarr = JSONArray.fromObject(params.get("stationList"));
			List<SysUserStation> stationList = new ArrayList<SysUserStation>();
			for (Object obj : jarr) {
				JSONObject jobj = JSONObject.fromObject(JSONObject.fromObject(obj).get("data"));
				SysUserStation us = new SysUserStation();
				us.setId(UuidUtil.get32UUID());
				us.setStationId(jobj.getString("id"));
				us.setUserId(userId);
				stationList.add(us);
			}
			ModifyAnnotaionFactory.newInstance().ModifyAnnotation(getClass(), UserOperateLog.class, "setUserStation",
					"bussid", userId, Map.class);
			User userOp = UserUtil.getUser();
			userService.setUserStation(userId, stationList, userOp);
			return R.ok();
		} catch (Exception e) {
			log.error("设置用户岗位失败", e);
			return R.error(1, "设置用户岗位失败");
		}
	}

	/**
	 * 
	 * 系统管理员给用户重置密码
	 * 
	 * @param userId
	 * @return
	 */
	@UserOperateLog(module = "系统功能", methods = "resetPassword", description = "重置密码")
	@GetMapping("/resetPassword/{userId}")
	public R resetPassword(@PathVariable("userId") String userId) {
		try {
			if (userId.equals(UserUtil.getUser().getId())) {
				return R.error("不要重置自己的密码！");
			}
			String password = userService.resetPassword(userId, UserUtil.getUser());
			return R.ok().put("random", password);
		} catch (Exception e) {
			log.error("重置密码失败", e);
			return R.error("重置密码失败！");
		}
	}

	/**
	 * 批量删除
	 * @param userIds
	 * @return
	 */
	@UserOperateLog(module = "系统功能", methods = "delete", description = "删除用户")
	@PostMapping("/delete")
	// @RequiresPermissions("sys:user:delete")
	public R delete(@RequestBody String[] userIds) {
		User userOp = (User) UserUtil.getUser();
		if (ArrayUtils.contains(userIds, "1")) {
			return R.error("系统管理员不能删除");
		}

		if (ArrayUtils.contains(userIds, userOp.getId())) {
			return R.error("当前用户不能删除");
		}
		userService.deleteBatch(userIds);
		return R.ok();
	}

	/**
	 * 根据租户和用户id加载资源树权限
	 * 
	 * @param tenantId
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/getTenantUserResTree/{tenantId}/{id}")
	public R getTenantUserResTree(@PathVariable("tenantId") String tenantId, @PathVariable("id") String id)
			throws Exception {
		User user = UserUtil.getUser();
		if (!user.getTenantId().equals(Constant.SUPER_ADMIN_TENANTID)) {
			tenantId = user.getTenantId();
		}
		List<TreeUtils> list = tenantService.getTenantRoleResTree(tenantId);
		List<SysUserMenu> asingRes = new ArrayList<SysUserMenu>();
		asingRes = userService.getResTreeByUserId(id);
		return R.ok().put("tree", list).put("asingRes", asingRes);
	}

	/**
	 * 设置用户资源
	 * 
	 * @param userRes
	 * @return
	 */
	@PostMapping("/setSysUserMenu")
	@UserOperateLog(module = "系统功能", methods = "setSysUserMenu", description = "设置用户资源权限", functionNo = "101059")
	public R setSysUserMenu(@RequestBody UserRes userRes) {
		try {
			User userSession = UserUtil.getUser();
			userService.setSysUserMenu(userRes, userSession);
			ModifyAnnotaionFactory.newInstance().ModifyAnnotation(getClass(), UserOperateLog.class, "setSysUserMenu",
					"bussid", userRes.getId().toString(), userRes.getClass());
			return R.ok();
		} catch (Exception e) {
			log.error("设置资源权限失败", e);
			return R.error("设置资源权限失败");
		}
	}

	/**
	 * 查找所有的用户
	 *
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/getAllUserByTenantId")
	public List<User> getAllUserByTenantId() throws Exception {
		User user = UserUtil.getUser();
		List<User> userList = userService.getAllUserByTenantId(user.getTenantId());
		return userList;
	}
}
